﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Data;
using System.IO;
using Schedule;
using System.Runtime.InteropServices;
using System.Threading;
using System.Globalization;
using System.Configuration;
using System.Diagnostics;
using Microsoft.Win32;

namespace MulticastTV
{
    /// <summary>
    /// Main application. Notify icon and timer.
    /// </summary>
     public static class StandBy 
    {
        [DllImport("kernel32.dll")]
        public static extern IntPtr CreateWaitableTimer(IntPtr
        lpTimerAttributes,
        bool bManualReset, string lpTimerName);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool SetWaitableTimer(IntPtr hTimer, ref long
        pDueTime, int period, IntPtr pfnCompletionRoutine, IntPtr
        lpArgToCompletionRoutine, bool fResume);

        [DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
        public static extern Int32 WaitForSingleObject(IntPtr handle, uint
        milliseconds);

        [DllImport("kernel32.dll")]
        static extern bool CancelWaitableTimer(IntPtr hTimer);

        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        public static bool toTray = false;
       
        static Thread standbyThread;

        /// <summary>
        /// Application startup path
        /// </summary>
        static string path = Application.StartupPath;

        /// <summary>
        /// Rec folder
        /// </summary>
        static string recfolder="";

        /// <summary>
        /// Iptv network interface ip.
        /// </summary>
        static string interfacename="";

        /// <summary>
        /// Recording schedule timer.
        /// </summary>
        static ScheduleTimer TickTimer;
         
        static char[] plusdelimiter = { '+' };
        static char[] semicolondelimiter = { ';' };
        static char[] colondelimiter = { ':' };

        /// <summary>
        /// Main form (video).
        /// </summary>
        public static Form1 mainform;

        /// <summary>
        /// Scheduler form.
        /// </summary>
        static RecForm schedule;

        /// <summary>
        /// Notify icon.
        /// </summary>
       static  public NotifyIcon appIcon = new NotifyIcon();
       
         /// <summary>
        /// Single click delay - so double click is processed first
        /// </summary>
      static System.Windows.Forms.Timer clickDelay = new System.Windows.Forms.Timer();
        
       /// <summary>
       /// Context menu for notify icon.
       /// </summary>
       static public ContextMenu sysTrayMenu = new ContextMenu();

       static string ni_prev = "Prev";
       static string ni_next = "Next";
       static string ni_schedule = "SChedule";
       static string ni_show = "Show";
       static string ni_exit = "Exit";

       static bool DoubleClick = false;

       /// <summary>
       /// Start multicastTV
       /// </summary>
       /// <param name="minimized">Don't show main form</param>
       static public void Start(bool minimized)
        {
            //upgrade settings
            try
            {
                if (Properties.Settings.Default.UpgradeSettings)
                {
                    Properties.Settings.Default.Upgrade();
                    Properties.Settings.Default.UpgradeSettings = false;
                }
            }
            catch (System.Configuration.ConfigurationException ex)
            { 
                string filename = ((System.Configuration.ConfigurationException)ex.InnerException).Filename;
                File.Delete(filename);
                Application.Restart();
                Process.GetCurrentProcess().Kill();
            }
            
            recfolder = Properties.Settings.Default.RecFolder;
            interfacename = Properties.Settings.Default.InterfaceName;
            setLanguage();

            if (Properties.Settings.Default.language == "Slovenian")
            {
                // !!! HARDCODED TRANSLATION! Use MLmessages.resx !
                ni_prev = "Naslednji";
                ni_next = "Prejšni";
                ni_schedule = "Nastavi Snemanje";
                ni_show = "Prikaži";
                ni_exit = "Izhod";
            }

            MenuItem ninext = new MenuItem(ni_next);
            ninext.Enabled = false;
            MenuItem niprev = new MenuItem(ni_prev);
            niprev.Enabled = false;
            MenuItem showSchedule = new MenuItem(ni_schedule);
            MenuItem showDialog = new MenuItem(ni_show);
            MenuItem exitApp = new MenuItem(ni_exit);

            Icon ico = Properties.Resources.icon16x16;
            appIcon.Icon = ico;
            appIcon.Text = "MulticastTV";

            // Place the menu items in the menu.
             sysTrayMenu.MenuItems.Add(ninext);
             sysTrayMenu.MenuItems.Add(niprev);
             sysTrayMenu.MenuItems.Add("-");
             sysTrayMenu.MenuItems.Add(showDialog);
             sysTrayMenu.MenuItems.Add(showSchedule);
             sysTrayMenu.MenuItems.Add(exitApp);
             appIcon.ContextMenu = sysTrayMenu;

             clickDelay.Interval = SystemInformation.DoubleClickTime + 60;
             clickDelay.Tick+=new EventHandler(clickDelay_Tick);
           
             // Show the system tray icon.
             appIcon.Visible = true;

             // Create application data directory if doesn't exists
             if (!Directory.Exists(Globals.UserAppPath))
             {
                 Directory.CreateDirectory(Globals.UserAppPath);
             }
                 
            // Ask for import
             if (!File.Exists(Globals.UserAppPath + @"\..\channellist.xml") && !File.Exists(Globals.UserAppPath + @"\..\import.atvlist"))
             {
                 ImportChannelsForm import = new ImportChannelsForm(Globals.UserAppPath);
                 import.StartPosition = FormStartPosition.CenterScreen;
                 import.ShowDialog();
             }
            
            // Default rec folder
             if (recfolder.Length == 0)
             {
                 try
                 {
                     recfolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + @"\MulticastTV";
                     Properties.Settings.Default.RecFolder = recfolder;
                 }
                 catch { }
             }
             if (!Directory.Exists(recfolder))
             {
                 try
                 {
                     Directory.CreateDirectory(recfolder);
                 }
                 catch { MessageBox.Show("Can't create default recording folder."); }
             }
             
            // Get interface name and convert it to ip
             Interfaces intf = new Interfaces();
            if (interfacename.Length == 0)
             {
                 try
                 {
                     string name = intf.getNames()[0];
                     string ip=intf.getIpFromName(name);
                     Properties.Settings.Default.InterfaceName =name;
                     Globals.interfaceip = ip;
                 }
                 catch { MessageBox.Show("Can't get local ip. "); Globals.interfaceip = ""; }
             }
             else
            {
                 try 
                 {
                    Globals.interfaceip = intf.getIpFromName(Properties.Settings.Default.InterfaceName);
                 }
                 catch { MessageBox.Show("Can't get local ip. "); Globals.interfaceip = ""; }
             }

            // Get interface index
            Interfaces intfi = new Interfaces();
            Globals.interfaceindex = intfi.getIndexFromName(Properties.Settings.Default.InterfaceName).ToString();

             // Workaround for libvlc NIC selection bug
            if (Properties.Settings.Default.VistaHack == 0)
            {
                Globals.determineInterfaceByIndex = (isVista64() || runingOnWin7());
            }
            else if (Properties.Settings.Default.VistaHack == 1)
            {
                Globals.determineInterfaceByIndex = false;
            }
            else if (Properties.Settings.Default.VistaHack == 2)
            {
                Globals.determineInterfaceByIndex = true;
            }
                  
             // Load recording xml if exists.
            if (File.Exists(Globals.UserAppPath + @"\..\schedule.xml"))
             {
                 try
                 {
                     RecTableContainer.dt.ReadXml(Globals.UserAppPath + @"\..\schedule.xml");
                 }
                 catch { }
             }
             
            // Datatable: each line one ip + favourite bool -- we create this from channels table
            if (!File.Exists(Globals.UserAppPath + @"\..\channellist.xml"))
             {
                 fillChannelTable(string.Empty);
              }
             else
             {
                 try
                 {
                     ChannelTable.menu.Tables["Menu"].ReadXml(Globals.UserAppPath + @"\..\channellist.xml");
                 }
                 catch { }
             }
 
            // Events
            showSchedule.Click+=new EventHandler(showSchedule_Click);
            showDialog.Click+=new EventHandler(showDialog_Click);
            exitApp.Click+=new EventHandler(exitApp_Click);
            ninext.Click+=new EventHandler(ninext_Click);
            niprev.Click+=new EventHandler(niprev_Click);
            appIcon.MouseClick += new MouseEventHandler(appIcon_MouseUp);
            appIcon.MouseDoubleClick+=new MouseEventHandler(appIcon_MouseDoubleClick);
            
            SystemEvents.SessionEnding+=new SessionEndingEventHandler(SystemEvents_SessionEnding);
            Application.ApplicationExit+=new EventHandler(Application_ApplicationExit);

            // Start timer.
            TickTimer = new ScheduleTimer();
            loadTimerJobs();

            handle = CreateWaitableTimer(IntPtr.Zero, false, "WakeupTimer");
            prepeareWakeupTimer();

            showMainForm(minimized);

        }

       static private void showMainForm(bool minimized)
       {
            if (!minimized)
            {
                appIcon.ContextMenu.MenuItems[0].Enabled = true;
                appIcon.ContextMenu.MenuItems[1].Enabled = true;
                mainform = new Form1(path,recfolder);
                mainform.Show();
            }
            else  mainform = null;
        }
       
       public delegate void TimerCallBack(string ip, string name, DataRow dr, Rec rf, int action);

       /// <summary>
       /// Load recording jobs from Recording table.
       /// </summary>
       static public void loadTimerJobs()
        {
            TickTimer.Stop();
            TickTimer.ClearJobs();
            TickTimer.Dispose();
            TickTimer = new ScheduleTimer();
         
            foreach (DataRow drow in RecTableContainer.dt.Tables["Recordings"].Rows)
            {
                DateTime start = ((DateTime)drow[0]);
                DateTime stop = ((DateTime)drow[1]);
                string ip = (string)drow[5];
                string name;
                name = (string)drow[2];
                string repeat;
                repeat = (string)drow[4];
                string status = (string)drow[6];
                Rec sched = new Rec();
                int action = 0;
                int.TryParse(drow[9].ToString(), out action);
                
                if (repeat.Contains("daily"))
                {
                    TickTimer.AddJob(new Schedule.ScheduledTime("Daily", start.ToString("HH:mm:ss")), new TimerCallBack(sched_start), ip, name, drow, sched, action);
                    TickTimer.AddJob(new Schedule.ScheduledTime("Daily", stop.AddSeconds(-1).ToString("HH:mm:ss")), new TimerCallBack(sched_stop), ip, name, drow, sched, action);
                }
                else if (repeat.Contains("weekly"))
                {
                    TickTimer.AddJob(new Schedule.ScheduledTime("Weekly", (int)start.DayOfWeek + "," + start.ToString("HH:mm:ss")), new TimerCallBack(sched_start), ip, name, drow, sched, action);
                    TickTimer.AddJob(new Schedule.ScheduledTime("Weekly", (int)stop.DayOfWeek + "," + stop.AddSeconds(-1).ToString("HH:mm:ss")), new TimerCallBack(sched_stop), ip, name, drow, sched, action);
                }
                else
                {
                    if (status != "recording")
                    {
                        TickTimer.AddJob(new Schedule.SingleEvent(start), new TimerCallBack(sched_start), ip, name, drow, sched, action);
                        TickTimer.AddJob(new Schedule.SingleEvent(stop.AddSeconds(-1)), new TimerCallBack(sched_stop), ip, name, drow, sched, action);
                    }
                    else 
                    {
                        // Recording has allready started - add only stop date.
                        TickTimer.AddJob(new Schedule.SingleEvent(stop.AddSeconds(-1)), new TimerCallBack(sched_stop), ip, name, drow, (Rec)drow[8], action);
                    }
                }
            }
           TickTimer.Stop();
           TickTimer.Start();
        }

       static  public void callLoadTimerJobs() 
       {
            loadTimerJobs();       
       }

       /// <summary>
       /// Start recording 
       /// </summary>
       /// <param name="ip">Multicast group to record</param>
       /// <param name="name">File name</param>
       /// <param name="rf">RecToFile object</param>
       /// <param name="action"></param>
        static public void sched_start(string ip, string name, DataRow dr, Rec rf, int action)
        {
            DateTime curdate = DateTime.Now;
            string filename = dr[7].ToString();
            rf.start(recfolder, curdate.ToString("yyyyMMddHHmmss-"), name, path, ip, filename);

            dr[6] = "recording";
            dr[8] = rf;
            appIcon.BalloonTipIcon = ToolTipIcon.Info;
            
            // TODO : Use MLmessages.resx
            if (Properties.Settings.Default.language == "Slovenian")
                appIcon.BalloonTipTitle = "Začetek snemanja";
            else
                appIcon.BalloonTipTitle = "Recording started";
            
            appIcon.BalloonTipText = name + "  " + curdate.ToString("HH:mm");
            appIcon.ShowBalloonTip(5000);
        }

        /// <summary>
        /// Stop recording
        /// </summary>
        /// <param name="ip">Multicast group to record</param>
        /// <param name="name">File name</param>
        /// <param name="rf">RecToFile object</param>
        /// <param name="action">Power action (standby, hibernate) after finish</param>
       static public void sched_stop(string ip, string name, DataRow dr, Rec rf, int action)
        {
            rf.stop();

            dr[6] = "done";
           // dr["object"] = null;
            appIcon.BalloonTipIcon = ToolTipIcon.Info;
            if (Properties.Settings.Default.language == "Slovenian")
                appIcon.BalloonTipTitle = "Snemanje končano";
            else
                appIcon.BalloonTipTitle = "Recording finished";
            appIcon.BalloonTipText = name + "  " + DateTime.Now.ToString("HH:mm");
            appIcon.ShowBalloonTip(5000);

            //save recording table
            RecTableContainer.dt.Tables["Recordings"].WriteXml(Globals.UserAppPath + @"\..\schedule.xml");

           // start action 
            if (action > 0)
            { 
                //standby
                CancelActionForm ca = new CancelActionForm(action);
                ca.ShowDialog();
             }
        }

       static  private void showSchedule_Click(object sender, System.EventArgs e)
       {
            if (!Globals.RecTableAllreadyOpenned)
            {
                schedule = new RecForm(path);
                Globals.RecTableAllreadyOpenned = true;
                schedule.ShowDialog();
                Globals.RecTableAllreadyOpenned = false;
            }
       }

      static  private void showDialog_Click(object sender, System.EventArgs e)
      {
            showForm();
      }

      static public void showForm()
      { 
           if (mainform == null )
            {
                appIcon.ContextMenu.MenuItems[0].Enabled = true;
                appIcon.ContextMenu.MenuItems[1].Enabled = true;
                mainform = new Form1(path,recfolder);
                mainform.Show();
            }
            else {
                mainform.Visible = true;
                mainform.WindowState = FormWindowState.Normal;
                mainform.Activate();
            }
      }

      static  private void exitApp_Click(object sender, System.EventArgs e)
      {
          if (mainform != null)
              mainform.Close(); // This triggers application  exit on close event.
          else
          {
              // scheduler check 2/2
              if (Globals.RecInstanceCount != 0)
              {
                  if (MessageBox.Show(MLmessages.RecAllowAbort, "", MessageBoxButtons.YesNo) == DialogResult.No)
                  {
                      return;
                  }
              }
              Application.Exit();
          }
      }

      static private void ninext_Click(object sender, System.EventArgs e)
      {
          if (mainform != null)
          {
              mainform.chUpDown("Down");
          }
      }
     
      static private void niprev_Click(object sender, System.EventArgs e)
      {
          if (mainform != null)
          {
              mainform.chUpDown("Up");
          }
      }

      static void clickDelay_Tick(object sender, EventArgs e)
      {
          clickDelay.Stop();
          mainform.chUpDown("Up");
      }

      static private void appIcon_MouseDoubleClick(object sender, MouseEventArgs e)
      {
          if (e.Button == MouseButtons.Left)
          {
              clickDelay.Stop();
              DoubleClick = true;
              showForm();
          }
          else if (e.Button == MouseButtons.Right)
          { 
             //?
          }
     }

      static private void appIcon_MouseUp(object sender, MouseEventArgs e)
      {
            if (e.Button == MouseButtons.Left)
            {
                if (mainform != null && !DoubleClick)
                {
                     clickDelay.Start();
                }
            }
            if (e.Button == MouseButtons.Middle)
            {
                if (mainform != null)
                {
                    mainform.chUpDown("Down");
                }
            }
            DoubleClick = false;
       }

       static private void Application_ApplicationExit(object sender, System.EventArgs e)
       {
            saveSettings();
            appIcon.Dispose();
       }

       static private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e )
       {
           saveSettings();
       }

       static private void saveSettings()
       {
           if (Globals.RecInstanceCount!= 0)
           {
               recShedulerOnExit();
               MessageBox.Show(MLmessages.RecWasAborted);
           }
           RecTableContainer.dt.Tables["Recordings"].WriteXml(Globals.UserAppPath + @"\..\schedule.xml");
           ChannelTable.menu.Tables["Menu"].WriteXml(Globals.UserAppPath + @"\..\channellist.xml");
           ChannelSettings.saveToFile();
           Properties.Settings.Default.Save();
       }

       /// <summary>
       /// Create internal channel information Datatable from file
       /// </summary>
       /// <param name="file">Input file</param>
       static public void fillChannelTable(string file) 
       {
           //Adittional informationm in case of m3u playlist.
           bool aditional = false;
           
           // Datatable each line one channel (multiple audio) ATVLIST IMPORT
           DataTable channels = Import.array(path, Globals.UserAppPath, file, ref aditional);
           if (channels == null)
           {
               return;
           }

           ChannelTable.menu.Tables["Menu"].Clear();
           DataTable groupst = new DataTable();
           bool failed = false;
           
           if (aditional)
           { 
             //Read xml
             groupst.Columns.Add("Name", typeof(string));
             groupst.Columns.Add("Group", typeof(string));
             groupst.Columns.Add("Audio", typeof(string));
             groupst.Columns["Name"].DefaultValue = "";
             groupst.Columns["Group"].DefaultValue = "";
             groupst.Columns["Audio"].DefaultValue = "";
             groupst.TableName = Thread.CurrentThread.CurrentCulture.IetfLanguageTag;
             groupst.PrimaryKey = new DataColumn[] {groupst.Columns["Name"] };
             try
             {
                if (Properties.Settings.Default.language=="Slovenian")
                     groupst.ReadXml(path + @"\parse\groups_sl-SI_utf8.xml");
                else
                     groupst.ReadXml(path + @"\parse\groups_default_utf8.xml");
             }
             catch { failed = true; }
           }
           
           foreach (DataRow dr in channels.Rows)
           {
               int i = 0;
               foreach (string str in (string[])dr["Ip"])
               {
                   DataRow menurow;
                   menurow = ChannelTable.menu.Tables["Menu"].NewRow();
                   menurow[0] = str.Split(plusdelimiter)[1];
                   menurow[1] = dr["Channel"];
                   menurow[2] = dr["Name"];
                   menurow[3] = dr["Group"];
                   menurow[4] = str.Split(plusdelimiter)[0];

                   if (aditional == true && !failed && groupst.Rows.Count > 0)
                   { 
                        // Here we get audio and language information if we imported from m3u.
                       DataRow tdt = groupst.Rows.Find(dr["Name"]);
                       if (tdt != null)
                       {
                           menurow[3] = tdt["Group"];
                           menurow[4] = tdt["Audio"];
                       }
                   }
                   
                   menurow[7] = "";
                   if (i > 0)
                       menurow[6] = (bool)true;
                   else
                       menurow[6] = (bool)false;

                   bool exists = false;
                   //check if input is unique
                   foreach (DataRow drc in ChannelTable.menu.Tables["Menu"].Rows)
                   { 
                        if (String.Equals(drc[0].ToString(),menurow[0].ToString()))
                        {
                            exists = true;
                        }
                   }
                   if (!exists)
                     ChannelTable.menu.Tables["Menu"].Rows.Add(menurow);

                   i++;
               }
           }

           //Save this datatable to file
           ChannelTable.menu.Tables["Menu"].WriteXml(Globals.UserAppPath + @"\..\channellist.xml");
       }

        static IntPtr handle;

        /// <summary>
        /// Set global timer that wakes up computer from standby
        /// </summary>
        /// <param name="firstStart">Start DateTime</param>
       static void setWakeupTimer(DateTime firstStart)
       {
           if (standbyThread == null)
           { 
                standbyThread = new Thread(restartTimer);
                standbyThread.IsBackground = true;
                standbyThread.Start();
           }
             
            firstStart = firstStart.AddSeconds(-30);
            firstStart.ToUniversalTime();
            long duetime = firstStart.ToFileTime();

            SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero,IntPtr.Zero, true);
       }

       static List<DateTime> startcollection;

       /// <summary>
       /// Find the closest DateTime for computer wakeup from scheduler table.
       /// </summary>
       public static void prepeareWakeupTimer()
       {
           startcollection=new List<DateTime>();
           DateTime curtime = DateTime.Now;
           DateTime closestDate=DateTime.MaxValue;
           double mindiff = double.MaxValue;
           startcollection.Clear();

           foreach (DataRow row in RecTableContainer.dt.Tables["Recordings"].Rows)
           {
               DateTime start;
               string rep = (string)row[4];
               start = (DateTime)row[0];
               if (rep == "")
               {
                   // leave it
               }
               else if (rep.Contains("daily"))
               {
                   DateTime passtime =  (DateTime)row[0];
                   // Date is in the future so load it.
                   if (passtime.Subtract(curtime).TotalSeconds > 0)
                   {
                       start = passtime;
                   }
                   else
                   {
                       // Get hours and minutes and set it as today's date.
                       start = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, passtime.Hour, passtime.Minute, passtime.Second);
                       if (start.Subtract(curtime).TotalSeconds < 0)
                       {
                            start = start.AddDays(1);
                       }
                   }
               }
               else if (rep.Contains("weekly"))
               {
                   DateTime passtime = (DateTime)row[0];
                   // Date is in the futire so load it
                   if (passtime.Subtract(curtime).TotalSeconds > 0)
                   {
                       start = passtime;
                   }
                   else
                   {
                       // Get hours and minutes and set it as today's date.
                       start = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, passtime.Hour, passtime.Minute, passtime.Second);

                       // Add correct number of days to get the same day of week.
                       while (start.DayOfWeek != passtime.DayOfWeek)
                       {
                           start = start.AddDays(1);
                       }
                       // Set it for the next week if the date has allready passed,
                       if (start.Subtract(curtime).TotalSeconds < 0)
                       {
                           start = start.AddDays(7);
                       }
                   }
               }

               double diff = start.Subtract(curtime).TotalSeconds;
               if (diff>=0)
                   startcollection.Add(start);
           }
           foreach (DateTime start in startcollection)
           {
               double diff = start.Subtract(curtime).TotalSeconds;
               if (diff < mindiff)
               {
                   mindiff = diff;
                   closestDate = start;
               }
           }

           if (closestDate != DateTime.MaxValue)
               setWakeupTimer(closestDate);
       }

       //Application exits while still recording - update status.
       private static void recShedulerOnExit()
       { 
            foreach (DataRow drow in RecTableContainer.dt.Tables["Recordings"].Rows)
            {
                string status = (string)drow[6];
                if (status == "recording")
                {
                    drow[6]= "done";
                }
            }
       }

       private static void restartTimer()
       {
          uint INFINITE = 0xFFFFFFFF;
          do
          {
             int i = WaitForSingleObject(handle, INFINITE);
             Thread.Sleep(40*1000); // Set next wakeup timer, 10s after recording started (40s - 30s)
             prepeareWakeupTimer();
          } while (true);
       }

       private static void setLanguage()
       {
           if (Thread.CurrentThread.CurrentCulture.IetfLanguageTag == "sl-SI" && Properties.Settings.Default.language == "default")
           {
               Properties.Settings.Default.language = "Slovenian";
               Properties.Settings.Default.Save();

           }
           if (Properties.Settings.Default.language == "Slovenian")
           {
               //sl-SI
               Thread.CurrentThread.CurrentUICulture = new CultureInfo("sl-SI");
           }
       }

       public static bool runingOnVista()
       {

           OperatingSystem os = Environment.OSVersion;
           Version vs = os.Version;
           if (os.Platform == PlatformID.Win32NT && vs.Major == 6)
           {
               return true;
           }
           else
           {
               return false;
           }
       }

       public static bool runingOnWin7()
       {

           OperatingSystem os = Environment.OSVersion;
           Version vs = os.Version;
           if (os.Platform == PlatformID.Win32NT && vs.Major == 6 && vs.Minor==1)
           {
               return true;
           }
           else
           {
               return false;
           }
       }

       public static bool isVista64()
       {
          
           OperatingSystem os = Environment.OSVersion;
           Version vs = os.Version;
           if (os.Platform == PlatformID.Win32NT && vs.Major == 6 && vs.Minor==0 && Is64bitOS)
           {
               return true;
           }
           else
           {
               return false;
           }
       }

       public static bool Is64bitOS
       {
           get { return (Environment.GetEnvironmentVariable("ProgramFiles(x86)") != null); }
       }

       public static string ProgramFilesX86
       {
           get
           {
               string programFiles = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
               if (programFiles == null)
               {
                   programFiles = Environment.GetEnvironmentVariable("ProgramFiles");
               }

               return programFiles;
           }
       }
    }
}

